package com.wugui.datax.admin.controller;

import com.baomidou.mybatisplus.extension.api.R;
import com.wugui.datax.admin.config.RuoYiConfig;
import com.wugui.datax.admin.dto.OracleTableDto;
import com.wugui.datax.admin.dto.TableNameDto;
import com.wugui.datax.admin.entity.GenTableColumn;
import com.wugui.datax.admin.exception.CustomException;
import com.wugui.datax.admin.service.DatasourceQueryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.List;
import java.util.UUID;

/**
 * 查询数据库表名，字段的控制器
 *
 * @author jingwk
 * @ClassName MetadataController
 * @Version 2.1.2
 * @since 2020/05/31 20:48
 */
@RestController
@RequestMapping("api/metadata")
@Api(tags = "jdbc数据库查询控制器")
public class MetadataController extends BaseController {

    protected static final Logger logger = LoggerFactory.getLogger(MetadataController.class);

    @Autowired
    private DatasourceQueryService datasourceQueryService;

    /**
     * 根据数据源id获取mongo库名
     *
     * @param datasourceId
     * @return
     */
    @GetMapping("/getDBs")
    @ApiOperation("根据数据源id获取mongo库名")
    public R<List<String>> getDBs(Long datasourceId) throws IOException {
        return success(datasourceQueryService.getDBs(datasourceId));
    }


    /**
     * 根据数据源id,dbname获取CollectionNames
     *
     * @param datasourceId
     * @return
     */
    @GetMapping("/collectionNames")
    @ApiOperation("根据数据源id,dbname获取CollectionNames")
    public R<List<String>> getCollectionNames(Long datasourceId, String dbName) throws IOException {
        return success(datasourceQueryService.getCollectionNames(datasourceId, dbName));
    }

    /**
     * 获取PG table schema
     *
     * @param datasourceId
     * @return
     */
    @GetMapping("/getDBSchema")
    @ApiOperation("根据数据源id获取 db schema")
    public R<List<String>> getTableSchema(Long datasourceId) {
        return success(datasourceQueryService.getTableSchema(datasourceId));
    }

    /**
     * 根据数据源id获取可用表名
     *
     * @param datasourceId
     * @return
     */
    @GetMapping("/getTables")
    @ApiOperation("根据数据源id获取可用表名")
    public R<List<String>> getTableNames(Long datasourceId, String tableSchema) throws IOException, SQLException {
        return success(datasourceQueryService.getTables(datasourceId, tableSchema));
    }

    /**
     * 根据数据源id获取可用表名
     *
     * @param datasourceId
     * @return
     */
    @GetMapping("/getTableNameAndComment")
    @ApiOperation("根据数据源id获取可用表名")
    public R<List<TableNameDto>> getTableName(Long datasourceId, String tableSchema) throws IOException, SQLException {
        return success(datasourceQueryService.getTableNameAndComment(datasourceId, tableSchema));
    }

    /**
     * 根据数据源id和表名获取所有字段
     *
     * @param datasourceId 数据源id
     * @param tableName    表名
     * @return
     */
    @GetMapping("/getColumns")
    @ApiOperation("根据数据源id和表名获取所有字段")
    public R<List<String>> getColumns(Long datasourceId, String tableName) throws IOException, SQLException {
        return success(datasourceQueryService.getColumns(datasourceId, tableName));
    }

    /**
     * 根据数据源id和sql语句获取所有字段
     *
     * @param datasourceId 数据源id
     * @param querySql     表名
     * @return
     */
    @GetMapping("/getColumnsByQuerySql")
    @ApiOperation("根据数据源id和sql语句获取所有字段")
    public R<List<String>> getColumnsByQuerySql(Long datasourceId, String querySql) throws SQLException {
        return success(datasourceQueryService.getColumnsByQuerySql(datasourceId, querySql));
    }

    /**
     * 根据数据源id和表名获取所有字段
     *
     * @param datasourceId 数据源id
     * @param tableName    表名
     * @return
     */
    @GetMapping("/getTableColumns")
    @ApiOperation("根据数据源id和表名获取所有字段")
    public R<List<GenTableColumn>> getTableColumns(Long datasourceId, String tableName) throws IOException, SQLException {
        return success(datasourceQueryService.getTableColumns(datasourceId, tableName));
    }

    /**
     * 生产oracleDLL
     *
     * @param oracleTableDto 数据
     * @return
     */
    @PostMapping("/generateOracleDdl")
    @ApiOperation("生成oracleDLL")
    public R<String> generateOracleDdl(@RequestBody OracleTableDto oracleTableDto) {
        return success(datasourceQueryService.generateOracleDdl(oracleTableDto));
    }

    /**
     * 生成oracle的数据字典
     *
     * @param oracleTableDto 数据
     * @return
     */
    @PostMapping("/generateOracleDict")
    @ApiOperation("生成oracle的数据字典")
    public R<List<GenTableColumn>> generateOracleDict(@RequestBody OracleTableDto oracleTableDto) {
        return success(datasourceQueryService.generateOracleDict(oracleTableDto));
    }

    /**
     * 导出oracle的数据字典
     *
     * @param oracleTableDto 数据
     * @return
     */
    @PostMapping("/exportOracleDict")
    @ApiOperation("导出oracle的数据字典")
    public R<String> exportOracleDict(@RequestBody OracleTableDto oracleTableDto, HttpServletResponse response, HttpServletRequest request) {
        Workbook workbook = null;
        OutputStream out = null;
        try {
            String fileName = UUID.randomUUID().toString() + "_" + oracleTableDto.getFullTableName() + ".xlsx";
            workbook = datasourceQueryService.exportOracleDict(fileName, oracleTableDto);
            out = new FileOutputStream(RuoYiConfig.getAbsoluteFile(fileName));
            workbook.write(out);
            return R.ok(fileName);
        } catch (Exception e) {
            logger.error("下载文件失败", e);
            throw new CustomException("下载文件失败");
        } finally {
            if (out != null) {
                IOUtils.closeQuietly(out);
            }
            if (workbook != null) {
                IOUtils.closeQuietly(workbook);
            }
        }
    }


}
